﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 开关按钮控件
    /// </summary>
    [Description("开关按钮控件")]
    [DefaultProperty("Text")]
    [DefaultEvent("CheckedChanged")]
    [TypeConverter(typeof(PropertyOrderConverter))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(ToggleButton), "Controls.ToggleButton.Resources.ToggleButton.bmp")]
    public class ToggleButton : MainThreadAnimationControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(ToggleButton)).GetName().Name, typeof(ToggleButton).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled= SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            throw new NotImplementedException();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        private static readonly object EventCheckedChanged = new object();
        /// <summary>
        /// 开关状态更改事件
        /// </summary>
        [Description("开关状态更改事件")]
        public event EventHandler CheckedChanged
        {
            add { Events.AddHandler(EventCheckedChanged, value); }
            remove { Events.RemoveHandler(EventCheckedChanged, value); }
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        #endregion

        #region 新增属性

        private bool roundEnabled = true;
        /// <summary>
        /// 是否启用圆角
        /// </summary>
        [Description("是否启用圆角")]
        [Category("杂项")]
        [PropertyOrder(-198)]
        [DefaultValue(true)]
        public bool RoundEnabled
        {
            get { return this.roundEnabled; }
            set
            {
                if (this.roundEnabled == value)
                    return;

                this.roundEnabled = value;
                this.SetControlShape();
                this.Invalidate();
            }
        }

        private ContentAlignment textAlignment = ContentAlignment.MiddleCenter;
        /// <summary>
        /// 文本对齐方式
        /// </summary>
        [Description("文本对齐方式")]
        [Category("杂项")]
        [PropertyOrder(-183)]
        [DefaultValue(ContentAlignment.MiddleCenter)]
        public ContentAlignment TextAlignment
        {
            get { return this.textAlignment; }
            set
            {
                if (this.textAlignment == value)
                    return;

                this.textAlignment = value;
                this.Invalidate();
            }
        }

        private ImageList imageList;
        /// <summary>
        /// 获取在控件上显示的图像的ImageList
        /// </summary>
        [Description("获取在控件上显示的图像的ImageList ")]
        [Category("杂项")]
        [PropertyOrder(-180)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.Repaint)]
        public ImageList ImageList
        {
            get { return this.imageList; }
            set
            {
                if (imageList == value)
                    return;

                EventHandler recreateHandler = new EventHandler(this.RecreateImageListHandler);
                EventHandler disposedHandler = new EventHandler(this.DetachImageListHandler);

                if (this.imageList != null)
                {
                    this.imageList.RecreateHandle -= recreateHandler;
                    this.imageList.Disposed -= disposedHandler;
                }

                this.imageList = value;
                this.StyleAppearance.UnChecked.Normal.iconIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.UnChecked.Enter.iconIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.UnChecked.Disabled.iconIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.Checked.Normal.iconIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.Checked.Enter.iconIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.Checked.Disabled.iconIndexer.SyncIndexer(value);//同步索引管理器

                if (value != null)
                {
                    this.imageList.RecreateHandle += recreateHandler;
                    this.imageList.Disposed += disposedHandler;
                }
                this.Invalidate();
            }
        }

        private IcoObject icon;
        /// <summary>
        /// 图标
        /// </summary>
        [Description("图标")]
        [PropertyOrder(-178)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public IcoObject Icon
        {
            get
            {
                if (this.icon == null)
                    this.icon = new IcoObject(this);
                return this.icon;
            }
        }

        private bool autoCheck = true;
        /// <summary>
        /// 单击时是否自动更改控件状态
        /// </summary>
        [Description("单击时是否自动更改控件状态")]
        [Category("杂项")]
        [PropertyOrder(-175)]
        [DefaultValue(true)]
        public bool AutoCheck
        {
            get { return this.autoCheck; }
            set
            {
                if (this.autoCheck == value)
                    return;

                this.autoCheck = value;
            }
        }

        private bool _Checked = false;
        /// <summary>
        /// 是否已选中
        /// </summary>
        [Description("是否已选中")]
        [Category("杂项")]
        [PropertyOrder(-173)]
        [DefaultValue(false)]
        public bool Checked
        {
            get { return this._Checked; }
            set
            {
                if (this._Checked == value)
                    return;

                this._Checked = value;
                this.Invalidate();

                if (!this.DesignMode)
                {
                    this.OnCheckedChanged(new EventArgs());
                }
            }
        }

        /// <summary>
        /// 鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool IsMouseEnter
        {
            get { return this.mouseenterobject != null; }
        }

        #endregion

        #region 重写属性

        protected override Padding DefaultPadding
        {
            get { return new Padding(3, 3, 3, 3); }
        }

        protected override Size DefaultSize
        {
            get { return new Size(90, 24); }
        }

        public override string Text
        {
            get { return base.Text; }
            set
            {
                base.Text = value;
                this.Invalidate();
            }

        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Color BackColor
        {
            get { return this.Checked ? this.StyleAppearance.Checked.Normal.BackColor : this.StyleAppearance.UnChecked.Normal.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.Checked ? this.StyleAppearance.Checked.Normal.TextColor : this.StyleAppearance.UnChecked.Normal.TextColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 鼠标按下类型
        /// </summary>
        private MouseButtons mousedowntype = MouseButtons.None;
        /// <summary>
        /// 鼠标已进入对象
        /// </summary>
        private object mouseenterobject = null;

        /// <summary>
        /// 鼠标单击动画是否进行中
        /// </summary>
        private bool animationing = false;
        /// <summary>
        /// 鼠标单击动画动画总时间
        /// </summary>
        private double animationAllTime = 250;
        /// <summary>
        /// 鼠标单击动画已使用时间
        /// </summary>
        private double animationUsedTime = 0;
        /// <summary>
        /// 鼠标单击动画圆心坐标
        /// </summary>
        private Point animationpoint = Point.Empty;

        #endregion

        public ToggleButton()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);//自定义单击事件逻辑
            SetStyle(ControlStyles.StandardDoubleClick, false);//停用双加事件

            this.SetControlShape();
            this.OnSkinChanged();
        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;

            int radius = Math.Min(this.Width, this.Height);
            Padding scale_padding = new Padding((int)Math.Ceiling(this.Padding.Left * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Top * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Right * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Bottom * this.ScaleDpi));
            Size scale_icoSize = (!this.Icon.Visible) ? new Size(0, 0) : new Size((int)Math.Ceiling(this.Icon.Size.Width * this.ScaleDpi), (int)Math.Ceiling(this.Icon.Size.Height * this.ScaleDpi));

            Color border_color = Color.Empty;
            Color back_color = Color.Empty;
            Color text_color = Color.Empty;
            Image ico = null;
            bool ico_istmp = false;
            StyleAppearanceObject.StateAppearanceObject stateAppearance = this.Checked ? this.StyleAppearance.Checked : this.StyleAppearance.UnChecked;
            if (!this.Enabled)
            {
                back_color = stateAppearance.Disabled.BackColor;
                text_color = stateAppearance.Disabled.TextColor;
                border_color = stateAppearance.Disabled.BorderColor;

                Image tmp = this.Checked ? this.StyleAppearance.Checked.Disabled.Icon : this.StyleAppearance.UnChecked.Disabled.Icon;
                if (ico != null)
                {
                    ico = ControlHelper.CreateDisabledImage(tmp);
                    ico_istmp = false;
                }
                else
                {
                    ico = tmp;
                    ico_istmp = true;
                }
            }
            else if (this.mouseenterobject == this)
            {
                back_color = stateAppearance.Enter.BackColor;
                text_color = stateAppearance.Enter.TextColor;
                border_color = stateAppearance.Enter.BorderColor;
                ico = this.Checked ? this.StyleAppearance.Checked.Enter.Icon : this.StyleAppearance.UnChecked.Enter.Icon;
            }
            else
            {
                back_color = stateAppearance.Normal.BackColor;
                text_color = stateAppearance.Normal.TextColor;
                border_color = stateAppearance.Normal.BorderColor;
                ico = this.Checked ? this.StyleAppearance.Checked.Normal.Icon : this.StyleAppearance.UnChecked.Normal.Icon;
            }

            //背景
            SolidBrush back_sb = new SolidBrush(back_color);
            g.FillRectangle(back_sb, this.ClientRectangle);
            if (this.animationing)//点击动画
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                int animationRadius = (int)Math.Ceiling(ControlHelper.AdjustRectangleMaxRadiusForPoint(this.ClientRectangle, this.animationpoint) * this.animationUsedTime / this.animationAllTime * 10 / 8);
                back_sb.Color = ControlHelper.ConvertToAnimationColor(back_color);
                g.FillEllipse(back_sb, new RectangleF(this.animationpoint.X - animationRadius, this.animationpoint.Y - animationRadius, animationRadius * 2, animationRadius * 2));
                g.SmoothingMode = SmoothingMode.Default;
            }
            back_sb.Dispose();

            //图标
            if (this.Icon.Visible && ico != null)
            {
                Rectangle ico_rect = new Rectangle(0, 0, scale_icoSize.Width, scale_icoSize.Height);
                if (this.Icon.Alignment == ContentAlignment.TopLeft || this.Icon.Alignment == ContentAlignment.MiddleLeft || this.Icon.Alignment == ContentAlignment.BottomLeft)
                {
                    ico_rect.X = this.ClientRectangle.X + scale_padding.Left;
                }
                else if (this.Icon.Alignment == ContentAlignment.TopCenter || this.Icon.Alignment == ContentAlignment.MiddleCenter || this.Icon.Alignment == ContentAlignment.BottomCenter)
                {
                    ico_rect.X = this.ClientRectangle.X + (this.ClientRectangle.Width - scale_icoSize.Width) / 2;
                }
                else if (this.Icon.Alignment == ContentAlignment.TopRight || this.Icon.Alignment == ContentAlignment.MiddleRight || this.Icon.Alignment == ContentAlignment.BottomRight)
                {
                    ico_rect.X = this.ClientRectangle.Right - scale_padding.Right - scale_icoSize.Width;
                }

                if (this.Icon.Alignment == ContentAlignment.TopLeft || this.Icon.Alignment == ContentAlignment.TopCenter || this.Icon.Alignment == ContentAlignment.TopRight)
                {
                    ico_rect.Y = this.ClientRectangle.Y + scale_padding.Top;
                }
                else if (this.Icon.Alignment == ContentAlignment.MiddleLeft || this.Icon.Alignment == ContentAlignment.MiddleCenter || this.Icon.Alignment == ContentAlignment.MiddleRight)
                {
                    ico_rect.Y = this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_icoSize.Height) / 2;
                }
                else if (this.Icon.Alignment == ContentAlignment.BottomLeft || this.Icon.Alignment == ContentAlignment.BottomCenter || this.Icon.Alignment == ContentAlignment.BottomRight)
                {
                    ico_rect.Y = this.ClientRectangle.Bottom - scale_padding.Bottom - scale_icoSize.Height;
                }

                g.DrawImage(ico, ico_rect);
                if (ico_istmp)
                {
                    ico.Dispose();
                }
            }

            // 文本
            g.SmoothingMode = SmoothingMode.Default;
            if (!String.IsNullOrWhiteSpace(this.Text))
            {
                NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
                SizeF text_size = new SizeF(g.MeasureString(this.Text, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width, font_metrics.GetFontRealHeight());

                RectangleF text_rect = new RectangleF(0, 0, text_size.Width, text_size.Height);
                if (this.TextAlignment == ContentAlignment.TopLeft || this.TextAlignment == ContentAlignment.MiddleLeft || this.TextAlignment == ContentAlignment.BottomLeft)
                {
                    text_rect.X = this.ClientRectangle.X + scale_padding.Left;
                }
                else if (this.TextAlignment == ContentAlignment.TopCenter || this.TextAlignment == ContentAlignment.MiddleCenter || this.TextAlignment == ContentAlignment.BottomCenter)
                {
                    text_rect.X = this.ClientRectangle.X + (this.ClientRectangle.Width - text_size.Width) / 2;
                }
                else if (this.TextAlignment == ContentAlignment.TopRight || this.TextAlignment == ContentAlignment.MiddleRight || this.TextAlignment == ContentAlignment.BottomRight)
                {
                    text_rect.X = this.ClientRectangle.Right - scale_padding.Right - text_size.Width;
                }

                if (this.TextAlignment == ContentAlignment.TopLeft || this.TextAlignment == ContentAlignment.TopCenter || this.TextAlignment == ContentAlignment.TopRight)
                {
                    text_rect.Y = this.ClientRectangle.Y + scale_padding.Top;
                }
                else if (this.TextAlignment == ContentAlignment.MiddleLeft || this.TextAlignment == ContentAlignment.MiddleCenter || this.TextAlignment == ContentAlignment.MiddleRight)
                {
                    text_rect.Y = this.ClientRectangle.Y + (this.ClientRectangle.Height - text_size.Height) / 2;
                }
                else if (this.TextAlignment == ContentAlignment.BottomLeft || this.TextAlignment == ContentAlignment.BottomCenter || this.TextAlignment == ContentAlignment.BottomRight)
                {
                    text_rect.Y = this.ClientRectangle.Bottom - scale_padding.Bottom - text_size.Height;
                }

                SolidBrush text_sb = new SolidBrush(text_color);
                g.DrawString(this.Text, this.Font, text_sb, text_rect.X, text_rect.Y, StringFormat.GenericTypographic);
                text_sb.Dispose();
            }

            //边框
            ControlHelper.DrawControlBorder(this, g, this.RoundEnabled, border_color, (this.Parent != null ? this.Parent.BackColor : back_color), back_color);

            //控件激活状态虚线框
            if (this.Focused && this.ShowFocusCues)
            {
                Pen activated_border_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot, Alignment = PenAlignment.Center };
                Rectangle activated_border_rect = new Rectangle(this.ClientRectangle.X + 3, this.ClientRectangle.Y + 3, this.ClientRectangle.Width - 7, this.ClientRectangle.Height - 7);
                g.DrawRectangle(activated_border_pen, activated_border_rect);
                activated_border_pen.Dispose();
            }

        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            this.mousedowntype = MouseButtons.None;
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!this.Enabled)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (!this.Visible)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.Parent == null)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);

            this.mouseenterobject = this;
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.mouseenterobject = null;
            this.Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (!this.Focused)
            {
                this.Focus();
            }

            this.mousedowntype |= e.Button;

            if (e.Button == MouseButtons.Left)
            {
                this.animationing = true;
                this.animationUsedTime = 0;
                this.animationpoint = e.Location;
                MainThreadAnimationControl.AnimationStart(this);
                this.Invalidate();
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.mousedowntype.HasFlag(MouseButtons.Left) && this.ClientRectangle.Contains(e.Location))
                {
                    this.OnClick(e);
                    this.OnMouseClick(e);
                    if (this.AutoCheck)
                    {
                        this.Checked = !this.Checked;
                    }
                }
            }
            this.mousedowntype &= ~e.Button;

            base.OnMouseUp(e);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.Space:
                    {
                        this.animationing = true;
                        this.animationUsedTime = 0;
                        this.animationpoint = new Point(this.ClientRectangle.X + this.ClientRectangle.Width / 2, this.ClientRectangle.Y + this.ClientRectangle.Height / 2);
                        MainThreadAnimationControl.AnimationStart(this);
                        this.Invalidate();
                        break;
                    }
            }

            base.OnKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.Space:
                    {
                        this.OnClick(EventArgs.Empty);
                        break;
                    }
            }

            base.OnKeyUp(e);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            this.SetControlShape();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                if (this.imageList != null)
                {
                    this.imageList.RecreateHandle -= new EventHandler(this.RecreateImageListHandler);
                    this.imageList.Disposed -= new EventHandler(this.DetachImageListHandler);
                    this.imageList = null;
                }
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 动画控件动画中要处理的内容(不能时耗时操作)
        /// </summary>
        /// <param name="interval">动画定时器间隔时间</param>
        protected override void Animationing(int interval)
        {
            bool finish = false;
            this.animationUsedTime += interval;
            if (this.animationUsedTime > this.animationAllTime)
            {
                this.animationUsedTime = this.animationAllTime;
                MainThreadAnimationControl.AnimationStop(this);
                finish = true;
            }

            if (finish)
            {
                this.animationing = false;
                this.animationUsedTime = 0;
                this.animationpoint = Point.Empty;
            }

            this.Invalidate();
        }

        #endregion

        #region 虚方法

        protected virtual void OnCheckedChanged(EventArgs e)
        {
            EventHandler handler = Events[EventCheckedChanged] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 设置控件形状
        /// </summary>
        private void SetControlShape()
        {
            GraphicsPath gp = new GraphicsPath();
            if (this.RoundEnabled)
            {
                gp = ControlHelper.AdjustRectangleShapePath(this.ClientRectangle);
            }
            else
            {
                gp.AddRectangle(this.ClientRectangle);
            }

            this.Region = new Region(gp);
            gp.Dispose();
        }

        /// <summary>
        /// ImageList更改后刷新控件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RecreateImageListHandler(object sender, EventArgs e)
        {
            if (this.IsHandleCreated)
            {
                this.Invalidate();
            }
        }

        /// <summary>
        /// ImageList释放时解绑清除清除引用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DetachImageListHandler(object sender, EventArgs e)
        {
            this.imageList = null;
        }

        #endregion

        #region 类

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class IcoObject
        {
            private ToggleButton owner = null;
            internal IcoObject(ToggleButton owner) { this.owner = owner; }

            #region 属性

            private bool visible = false;
            /// <summary>
            /// 是否显示图标
            /// </summary>
            [Description("是否显示图标")]
            [PropertyOrder(-182)]
            [DefaultValue(false)]
            public bool Visible
            {
                get { return this.visible; }
                set
                {
                    if (this.visible == value)
                        return;

                    this.visible = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private ContentAlignment alignment = ContentAlignment.MiddleLeft;
            /// <summary>
            /// 图标对齐方式
            /// </summary>
            [Description("图标对齐方式")]
            [PropertyOrder(-180)]
            [DefaultValue(ContentAlignment.MiddleLeft)]
            public ContentAlignment Alignment
            {
                get { return this.alignment; }
                set
                {
                    if (this.alignment == value)
                        return;

                    this.alignment = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private Size size = new Size(16, 16);
            /// <summary>
            /// 图标Size
            /// </summary>
            [Description("图标Size百分比")]
            [PropertyOrder(-176)]
            [DefaultValue(typeof(Size), "16,16")]
            public Size Size
            {
                get { return this.size; }
                set
                {
                    if (value.Width < 0)
                        value.Width = 0;
                    if (value.Height < 0)
                        value.Height = 0;
                    if (this.size == value)
                        return;

                    this.size = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinActivateColor = Color.Empty;
            private readonly Color defaultActivateColor = SystemColors.Window;
            private Color activateColor = Color.Empty;
            /// <summary>
            /// 控件激活的虚线框颜色
            /// </summary>
            [Description("控件激活的虚线框颜色")]
            [PropertyOrder(-200)]
            [SkinProperty(true, false)]
            public Color ActivateColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinActivateColor;
                    }

                    if (this.activateColor != Color.Empty)
                    {
                        return this.activateColor;
                    }

                    return this.defaultActivateColor;
                }
                set
                {
                    if (this.activateColor == value)
                        return;

                    this.activateColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeActivateColor()
            {
                return this.activateColor != Color.Empty;
            }
            private void ResetActivateColor()
            {
                this.activateColor = Color.Empty;
                this.Invalidate();
            }

            private StateAppearanceObject unChecked;

            /// <summary>
            /// 未选中状态外观
            /// </summary>
            [Description("未选中状态外观")]
            [PropertyOrder(-199)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public StateAppearanceObject UnChecked
            {
                get
                {
                    if (this.unChecked == null)
                        this.unChecked = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.InactiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                            );
                    return this.unChecked;
                }
            }

            private StateAppearanceObject _checked;
            /// <summary>
            /// 已选中状态外观
            /// </summary>
            [Description("已选中状态外观")]
            [Category("杂项")]
            [PropertyOrder(-192)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public StateAppearanceObject Checked
            {
                get
                {
                    if (this._checked == null)
                        this._checked = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                            );
                    return this._checked;
                }
            }

            #endregion

            public class StateAppearanceObject : AppearanceObjectBase
            {
                internal StateAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderNormalColor, Color backNormalColor, Color textNormalColor, Color borderEnterColor, Color backEnterColor, Color textEnterColor, Color borderDisabledColor, Color backDisabledColor, Color textDisabledColor) : base(owner, parent)
                {
                    this.borderNormalColor = borderNormalColor;
                    this.backNormalColor = backNormalColor;
                    this.textNormalColor = textNormalColor;
                    this.borderEnterColor = borderEnterColor;
                    this.backEnterColor = backEnterColor;
                    this.textEnterColor = textEnterColor;
                    this.borderDisabledColor = borderDisabledColor;
                    this.backDisabledColor = backDisabledColor;
                    this.textDisabledColor = textDisabledColor;
                }

                #region 属性

                private Color borderNormalColor = Color.Empty;
                private Color backNormalColor = Color.Empty;
                private Color textNormalColor = Color.Empty;
                private ItemAppearanceObject normal;
                /// <summary>
                /// 正常状态
                /// </summary>
                [Description("正常状态")]
                [PropertyOrder(-194)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Normal
                {
                    get
                    {
                        if (this.normal == null)
                            this.normal = new ItemAppearanceObject(this.owner, this, this.borderNormalColor, this.backNormalColor, this.textNormalColor);
                        return this.normal;
                    }
                }

                private Color borderEnterColor = Color.Empty;
                private Color backEnterColor = Color.Empty;
                private Color textEnterColor = Color.Empty;
                private ItemAppearanceObject enter;
                /// <summary>
                /// 鼠标进入状态
                /// </summary>
                [Description("鼠标进入状态")]
                [PropertyOrder(-192)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Enter
                {
                    get
                    {
                        if (this.enter == null)
                            this.enter = new ItemAppearanceObject(this.owner, this, this.borderEnterColor, this.backEnterColor, this.textEnterColor);
                        return this.enter;
                    }
                }

                private Color borderDisabledColor = Color.Empty;
                private Color backDisabledColor = Color.Empty;
                private Color textDisabledColor = Color.Empty;
                private ItemAppearanceObject disabled;
                /// <summary>
                /// 禁用状态
                /// </summary>
                [Description("禁用状态")]
                [PropertyOrder(-190)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Disabled
                {
                    get
                    {
                        if (this.disabled == null)
                            this.disabled = new ItemAppearanceObject(this.owner, this, this.borderDisabledColor, this.backDisabledColor, this.textDisabledColor);
                        return this.disabled;
                    }
                }

                #endregion

                public class ItemAppearanceObject : AppearanceObjectBase
                {
                    internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderColor, Color backColor, Color textColor) : base(owner, parent)
                    {
                        this.defaultBorderColor = borderColor;
                        this.defaultBackColor = backColor;
                        this.defaultTextColor = textColor;
                    }

                    #region 属性

                    private Color skinBorderColor = Color.Empty;
                    private readonly Color defaultBorderColor = Color.Empty;
                    private Color borderColor = Color.Empty;
                    /// <summary>
                    /// 边框颜色
                    /// </summary>
                    [Description("边框颜色")]
                    [PropertyOrder(-199)]
                    [SkinProperty(true, false)]
                    public Color BorderColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinBorderColor;
                            }

                            if (this.borderColor != Color.Empty)
                            {
                                return this.borderColor;
                            }

                            return this.defaultBorderColor;
                        }
                        set
                        {
                            if (this.borderColor == value)
                                return;

                            this.borderColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeBorderColor()
                    {
                        return this.borderColor != Color.Empty;
                    }
                    private void ResetBorderColor()
                    {
                        this.borderColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinBackColor = Color.Empty;
                    private readonly Color defaultBackColor = Color.Empty;
                    private Color backColor = Color.Empty;
                    /// <summary>
                    /// 背景颜色
                    /// </summary>
                    [Description("背景颜色")]
                    [PropertyOrder(-198)]
                    [SkinProperty(true, false)]
                    public Color BackColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinBackColor;
                            }

                            if (this.backColor != Color.Empty)
                            {
                                return this.backColor;
                            }

                            return this.defaultBackColor;
                        }
                        set
                        {
                            if (this.backColor == value)
                                return;

                            this.backColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeBackColor()
                    {
                        return this.backColor != Color.Empty;
                    }
                    private void ResetBackColor()
                    {
                        this.backColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinTextColor = Color.Empty;
                    private readonly Color defaultTextColor = Color.Empty;
                    private Color textColor = Color.Empty;
                    /// <summary>
                    /// 文本颜色
                    /// </summary>
                    [Description("文本颜色")]
                    [PropertyOrder(-197)]
                    [SkinProperty(true, false)]
                    public Color TextColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinTextColor;
                            }

                            if (this.textColor != Color.Empty)
                            {
                                return this.textColor;
                            }

                            return this.defaultTextColor;
                        }
                        set
                        {
                            if (this.textColor == value)
                                return;

                            this.textColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeTextColor()
                    {
                        return this.textColor != Color.Empty;
                    }
                    private void ResetTextColor()
                    {
                        this.textColor = Color.Empty;
                        this.Invalidate();
                    }

                    internal ImageIndexer iconIndexer = new ImageIndexer();
                    /// <summary>
                    /// 图标 
                    /// </summary>
                    [Description("图标")]
                    [PropertyOrder(-182)]
                    [DefaultValue(null)]
                    [SkinProperty(false, false)]
                    public Image Icon
                    {
                        get { return this.iconIndexer.Image; }
                        set
                        {
                            if (!this.iconIndexer.EqualImage(value))
                            {
                                this.iconIndexer.Image = value;
                                this.Invalidate();
                            }
                        }
                    }

                    /// <summary>
                    /// 图标Index 
                    /// </summary>
                    [Description("图标Index ")]
                    [PropertyOrder(-180)]
                    [DefaultValue(-1)]
                    [Localizable(true)]
                    [RefreshProperties(RefreshProperties.Repaint)]
                    [TypeConverter(typeof(ImageIndexConverter))]
                    [SkinProperty(false, false)]
                    public int IconIndex
                    {
                        get { return this.iconIndexer.Index; }
                        set
                        {
                            if (!this.iconIndexer.EqualIndex(value))
                            {
                                this.iconIndexer.Index = value;
                                this.Invalidate();
                            }
                        }
                    }

                    /// <summary>
                    /// 图标Key 
                    /// </summary>
                    [Description("图标Key ")]
                    [PropertyOrder(-178)]
                    [DefaultValue("")]
                    [Localizable(true)]
                    [RefreshProperties(RefreshProperties.Repaint)]
                    [TypeConverter(typeof(ImageKeyConverter))]
                    [SkinProperty(false, false)]
                    public string IconKey
                    {
                        get { return this.iconIndexer.Key; }
                        set
                        {
                            if (!this.iconIndexer.EqualKey(value))
                            {
                                this.iconIndexer.Key = value;
                                this.Invalidate();
                            }
                        }
                    }

                    #endregion

                }
            }

        }

        #endregion

    }

}
